package com.cd2cd.code_template.service.impl;

import com.cd2cd.code_template.code_template.domain.SysAuth;
import com.cd2cd.code_template.code_template.domain.SysGroup;
import com.cd2cd.code_template.code_template.domain.SysRelationAuth;
import com.cd2cd.code_template.code_template.domain.gen.SysAuthCriteria;
import com.cd2cd.code_template.code_template.domain.gen.SysRelationAuthCriteria;
import com.cd2cd.code_template.code_template.mapper.SysAuthMapper;
import com.cd2cd.code_template.code_template.mapper.SysGroupMapper;
import com.cd2cd.code_template.code_template.mapper.SysRelationAuthMapper;
import com.cd2cd.code_template.configuration.constants.ServiceCode;
import com.cd2cd.code_template.configuration.security.TokenUser;
import com.cd2cd.code_template.configuration.security.loginUserService.LoadUserService;
import com.cd2cd.code_template.service.SysAuthService;
import com.cd2cd.code_template.util.BeanUtil;
import com.cd2cd.code_template.util.CommUtils;
import com.cd2cd.code_template.vo.BaseRes;
import com.cd2cd.code_template.vo.SysAuthVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Component
public class SysAuthServiceImpl implements SysAuthService {


    @Resource
    private SysAuthMapper sysAuthMapper;

    @Resource
    private SysGroupMapper sysGroupMapper;


    @Override
    public BaseRes<List<SysAuthVo>> getAuthList(SysAuthVo sysAuthVo) {

        BaseRes<List<SysAuthVo>> res = new BaseRes<>(ServiceCode.SUCCESS);

        HashMap<String, Object> map = new HashMap<>();
        map.put("type", LoadUserService.Backend.class.getSimpleName());

        // 分级分权，获取上级权限
        String dataType = sysAuthVo.getDataType();
        Integer typeId = sysAuthVo.getTypeId();


        // 如果类型为 role 则查出当前登录用户所有权限 如果为group 则查出父级所有权限
        if (StringUtils.isNotBlank(dataType) && typeId != null && "group".equals(dataType)) {

            // 查出 pid
            SysGroup sysGroup = sysGroupMapper.selectByPrimaryKey(typeId);
            Integer pid = sysGroup.getPid();

            // 如果pid为0则为最上级 查询当前登录用户所有权限
            if (pid != null && pid != 0) {
                map.put("dataType", dataType);
                map.put("typeId", pid);
            }
        }

        TokenUser loginUserInfo = CommUtils.getLoginUserInfo();

        if (!"admin".equals(loginUserInfo.getUsername())) {
            map.put("userId",loginUserInfo.getUserId());
        }


        long count = sysAuthMapper.countByMap(map);

        if (count > 0) {
            List<SysAuth> sysAuths = sysAuthMapper.selectByMap(map);

            List<SysAuth> sysAuthNode = getParentAndSelfAuth(sysAuths);

            List<SysAuthVo> authVos = BeanUtil.voConvertList(sysAuthNode, SysAuthVo.class);

            Collections.sort(authVos);

            List<SysAuthVo> sysAuthVos = getSysAuthNode(authVos, 0);

            res.setData(sysAuthVos);
        }

        return res;
    }


    private List<SysAuth> getParentAndSelfAuth(List<SysAuth> self) {
        List<SysAuth> allAuth = sysAuthMapper.selectByExample(null);

        HashMap<Integer, SysAuth> authMap = new HashMap<>();
        Map<Integer, SysAuth> map = new HashMap<>();

        for (SysAuth sa : allAuth) {
            map.put(sa.getId(), sa);
        }

        for (SysAuth auth : self) {
            Integer id = auth.getId();
            authMap.put(id, auth);

            SysAuth sa = map.get(id);

            while (null != sa.getPid() && 0 != sa.getPid()) {
                sa = map.get(sa.getPid());
                authMap.put(sa.getId(), sa);
            }
        }

        List<SysAuth> list = new ArrayList<>();

        for (Integer s : authMap.keySet()) {
            list.add(authMap.get(s));
        }


        return list;
    }

    private List<SysAuthVo> getSysAuthNode(List<SysAuthVo> authList, Integer pid) {
        List<SysAuthVo> list = new ArrayList<>();

        for (SysAuthVo sysAuthVo : authList) {
            if (sysAuthVo.getPid().equals(pid)) {
                Integer id = sysAuthVo.getId();
                List<SysAuthVo> sysAuthNode = getSysAuthNode(authList, id);
                if (sysAuthNode.size() > 0) {
                    sysAuthVo.setChildren(sysAuthNode);
                }
                list.add(sysAuthVo);
            }
        }

        return list;
    }


}
